const ERROR_CODE = {
    1073741856: '请检查ADF是否卡纸', // 无错误
    1073741857: '检查到纸张重复进纸', // 无错误
    1073774594: '请检查是否缺纸', // 无错误
    1073774595: '请检查ADF盖板是否关闭', // 无错误
}

// 常量定义
const ESL_CONSTANTS = {
    // 扫描/保存事件类型
    EVENT_NONE: 0, // 无事件
    EVENT_SCANPAGE_COMPLETE: 1, // 扫描页完成
    EVENT_SAVEPAGE_COMPLETE: 2, // 保存页完成
    EVENT_ALLSCAN_COMPLETE: 3, // 所有扫描完成
    EVENT_ALLSAVE_COMPLETE: 4, // 所有保存完成

    // 文档来源定义
    SRC_AUTO: -1, // 自动
    SRC_FLATBED: 0, // 平板
    SRC_FEEDER_SIMPLEX: 1, // 单面进纸器
    SRC_FEEDER_DUPLEX: 2, // 双面进纸器

    // Image Type definitions
    IT_AUTO: -1, // 自动
    IT_COLOR: 0, // 彩色
    IT_GRAY: 1, // 灰度
    IT_MONO: 2, // 单色

    // Document Side definitions
    DS_AUTO_LONG: -2, // 自动长边
    DS_AUTO: -1, // 自动
    DS_USER: 0, // 用户
    DS_A3: 0x01, // A3
    DS_A4: 0x02, // A4
    DS_A5: 0x03, // A5
    DS_B4: 0x11, // B4
    DS_B5: 0x12, // B5
    DS_US_LEDGER: 0x21, // 美国信纸
    DS_US_LEGAL: 0x22, // 美国法律
    DS_US_LETTER: 0x23, // 美国信纸

    // Size Unit definitions
    SU_INCH: 0, // 英寸
    SU_CENTIMETER: 1, // 厘米
    SU_PIXEL: 2, // 像素

    // Document Rotation definitions
    DR_AUTO: -1, // 自动
    DR_NONE: 0, // 无旋转
    DR_R90: 1, // 90度旋转
    DR_R180: 2, // 180度旋转
    DR_R270: 3, // 270度旋转

    // Color Filter definitions
    CF_NONE: 0x00000000, // 无颜色滤镜
    CF_DROPOUT_RED: 0x00000001, // 丢弃红色
    CF_DROPOUT_GREEN: 0x00000002, // 丢弃绿色
    CF_DROPOUT_BLUE: 0x00000003, // 丢弃蓝色
    CF_DROPOUT_PINK: 0x00000004, // 丢弃粉色
    CF_DROPOUT_PURPLE: 0x00000005, // 丢弃紫色
    CF_DROPOUT_YELLOW: 0x00000006, // 丢弃黄色
    CF_DROPOUT_ORANGE: 0x00000007, // 丢弃橙色
    CF_DROPOUT_EXPBLACK: 0x00000008, // 丢弃黑色
    CF_ENHANCE_RED: 0x00000011, // 增强红色
    CF_ENHANCE_GREEN: 0x00000012, // 增强绿色
    CF_ENHANCE_BLUE: 0x00000013, // 增强蓝色
    CF_ENHANCE_PINK: 0x00000014, // 增强粉色
    CF_ENHANCE_PURPLE: 0x00000015, // 增强紫色
    CF_ENHANCE_YELLOW: 0x00000016, // 增强黄色
    CF_ENHANCE_ORANGE: 0x00000017, // 增强橙色
    CF_ENHANCE_EXPBLACK: 0x00000018, // 增强黑色

    // Document Enhance definitions
    DE_NONE: 0x00000000, // 无增强
    DE_TET_STD: 0x00000001, // 标准增强
    DE_TET_HIGH: 0x00000002,
    DE_AAS: 0x00000011,

    // Double Feed Detection definitions
    DFD_NONE: 0, // 无双面检测
    DFF_LOW: 1, // 低双面检测
    DFD_HIGH: 2, // 高双面检测

    // Blank Page Skip definitions
    BPS_NONE: 0, // 无空白页跳过
    BPS_VERY_LOW: 1, // 非常低空白页跳过
    BPS_LOW: 2, // 低空白页跳过
    BPS_MEDIUM: 3, // 中空白页跳过
    BPS_HIGH: 4, // 高空白页跳过

    //Image Filter
    ESL_IMGFILTER_USM: 0x00000001, // 使用USM滤镜
    ESL_IMGFILTER_DESCREENING: 0x00000002, // 使用去网滤镜


    // Punch Hole Remove definitions
    PHR_NONE: 0, // 无打孔去除
    PHR_ON: 1, // 打孔去除

    // Skew Correction definitions
    SC_NONE: 0, // 无倾斜校正
    SC_EDGE: 1, // 边缘校正
    SC_CONTENTS: 2, // 内容校正
    SC_BOTH: 3, // 两者校正

    // Edge Fill definitions
    EF_NONE: 0, // 无边缘填充
    EF_WHITE: 1, // 白色填充
    EF_BLACK: 2, // 黑色填充

    // Automatic Feeding Mode
    AFM_NONE: 0, // 无自动进纸
    AFM_ON: 1, // 自动进纸

    // LaminateCard Mode
    LCM_NONE: 0, // 无胶片模式
    LCM_ON: 1,

    // Destionation
    DEST_BASE64: 0, // Base64
    DEST_FILE: 1, // 文件

    // Save format
    FF_BMP: 0, // BMP
    FF_JPEG: 1, // JPEG
    FF_TIFF: 2, // TIFF
    FF_MULTITIFF: 3, // 多页TIFF
    FF_PDF: 4, // PDF

    // File name type
    FN_PREFIX: 0, // 前缀
    FN_BARCODE: 1, // 条形码
    FN_OCR: 2, // OCR

    // Time format
    TF_NONE: 0, // 无时间格式
    TF_YYYYMMDD: 1, // 年月日
    TF_MMDDYYYY: 2, // 月日年
    TF_DDMMYYYY: 3, // 日月年
    TF_YYYYMMDD_HHMMSS: 4, // 年月日时分秒
    TF_MMDDYYYY_HHMMSS: 5, // 月日年时分秒
    TF_DDMMYYYY_HHMMSS: 6, // 日月年时分秒


    // PDF Type
    PT_NORMAL: 0,	// Normal PDF document 标准PDF
    PT_PDF_A: 1,	// Make PDF/A document 制作PDF/A文档
    PT_HIGHCOMP: 2,	// HIgh Compression ADF document (Efficient for Color/Gray only) 高压缩ADF文档（适用于彩色/灰度）

    // OCR language
    OL_NONE: 0, // 无OCR语言
    OL_OCR_A: 1,		// OCR A Font (Not used for Searchable PDF)  OCR A字体（不适用于可搜索PDF）
    OL_OCR_B: 2,		// OCR B Font (Not used for Searchable PDF)  OCR B字体（不适用于可搜索PDF）
    OL_EN: 0x10,		// English 英语
    OL_ZH_TW: 0x12,		// Simplified Chinese 简体中文
    OL_ZH_CN: 0x13,		// Traditional Chinese 繁体中文
    OL_KO: 0x14,		// Korean 韩语
    OL_FR: 0x15,		// French 法语
    OL_IT: 0x16,		// Italian 意大利语
    OL_DE: 0x17,		// German 德语
    OL_ES: 0x18,		// Spanish 西班牙语
    OL_PT: 0x19,		// Portuguese 葡萄牙语
    OL_NL: 0x1A,		// Dutch 荷兰语
    OL_RU: 0x1B,		// Russian 俄语
    OL_UK: 0x1C,		// Ukrainian 乌克兰语

    DEFAULT_SERVER_URL: "http://localhost:51000" // 默认服务器URL
}

// ESL类定义
class ESLClass {
    constructor() {
        this.serverURL = ESL_CONSTANTS.DEFAULT_SERVER_URL; // 默认服务器URL
    }
    
    // 去除尾部斜杠
    StripTrailingSlash(str) {
        if (str.substr(-1) === '/') {
            return str.substr(0, str.length - 1);
        }
        return str;
    }
    
    // 打开
    Open(params, callback) {
        if (params.deviceName == null) {
            console.error("错误：deviceName不能为空");
            return;
        }
        
        if (params.serverURL) {
            this.serverURL = this.StripTrailingSlash(params.serverURL);
        }
        
        const requestXML = new XMLHttpRequest();
        requestXML.onreadystatechange = function() {
            if (requestXML.readyState === 4) {
                if (requestXML.status == 200) {
                    callback(true, JSON.parse(requestXML.responseText));
                } else {
                    callback(false, null);
                }
            }
        }
        
        requestXML.open("POST", this.serverURL + "/Open", true);
        requestXML.setRequestHeader("Content-Type", "text/plain");
        const json = JSON.stringify(params);
        requestXML.send(json);
    }
    
    Close(callback) {
        const requestXML = new XMLHttpRequest();
        requestXML.onreadystatechange = function() {
            if (requestXML.readyState === 4) {
                if (requestXML.status == 200) {
                    callback(true, JSON.parse(requestXML.responseText));
                } else {
                    callback(false, null);
                }
            }
        }
        
        requestXML.open("POST", this.serverURL + "/Close", true);
        requestXML.setRequestHeader("Content-Type", "text/plain");
        requestXML.send();
    }
    
    Cancel(callback) {
        const requestXML = new XMLHttpRequest();
        requestXML.onreadystatechange = function() {
            if (requestXML.readyState === 4) {
                if (requestXML.status == 200) {
                    callback(true, JSON.parse(requestXML.responseText));
                } else {
                    callback(false, null);
                }
            }
        }
        requestXML.open("POST", this.serverURL + "/Cancel", true);
        requestXML.setRequestHeader("Content-Type", "text/plain");
        requestXML.send(null);
    }

    GetInfo(callback) {
        const requestXML = new XMLHttpRequest();
        requestXML.onreadystatechange = function() {
            if (requestXML.readyState === 4) {
                if (requestXML.status == 200) {
                    callback(true, JSON.parse(requestXML.responseText));
                } else {
                    callback(false, null);
                }
            }
        }
        requestXML.open("POST", this.serverURL + "/GetInfo", true);
        requestXML.setRequestHeader("Content-Type", "text/plain");
        requestXML.send();
    }

    GetScanAndSaveEvent(callback) {
        const requestXML = new XMLHttpRequest();
        requestXML.onreadystatechange = function() {
            if (requestXML.readyState === 4) {
                if (requestXML.status == 200) {
                    callback(true, JSON.parse(requestXML.responseText));
                } else {
                    callback(false, null);
                }
            }
        }
        requestXML.open("POST", this.serverURL + "/GetScanAndSaveEvent", true);
        requestXML.setRequestHeader("Content-Type", "text/plain");
        requestXML.send(null);
    }

    Scan(params, callback) {
        const protypeThis = this;
        const requestXML = new XMLHttpRequest();
        requestXML.onreadystatechange = function() {
            if (requestXML.readyState === 4) {
                if (requestXML.status == 200) {
                    const checkScanStatus = function() {
                        protypeThis.GetScanAndSaveEvent(function(isSuccess, result) {
                            if (isSuccess) {
                                if (result.eventType == ESL_CONSTANTS.EVENT_NONE) {
                                    setTimeout(checkScanStatus, 1);
                                }
                                if (result.eventType == ESL_CONSTANTS.EVENT_SCANPAGE_COMPLETE) {
                                    callback(true, result);
                                    setTimeout(checkScanStatus, 1)
                                }
                                if (result.eventType == ESL_CONSTANTS.EVENT_ALLSCAN_COMPLETE) {
                                    if (result.errorCode == 0) {
                                        callback(true, result);
                                    } else {
                                        callback(false, result);
                                    }
                                }
                            } else {
                                callback(false, null);
                            }
                        });
                    };
                    setTimeout(checkScanStatus, 1);
                } else {
                    callback(false, null);
                }
            }
        }
        requestXML.open("POST", this.serverURL + "/Scan", true);
        requestXML.setRequestHeader("Content-Type", "text/plain");
        const json = JSON.stringify(params);
        requestXML.send(json);
    }

    Save(params, callback) {
        const protypeThis = this;
        const requestXML = new XMLHttpRequest();
        requestXML.onreadystatechange = function() {
            if (requestXML.readyState === 4) {
                if (requestXML.status == 200) {
                    const checkSaveStatus = function() {
                        protypeThis.GetScanAndSaveEvent(function(isSuccess, result) {
                            if (isSuccess) {
                                if (result.eventType == ESL_CONSTANTS.EVENT_NONE) {
                                    setTimeout(checkSaveStatus, 2);
                                }
                                if (result.eventType == ESL_CONSTANTS.EVENT_SAVEPAGE_COMPLETE) {
                                    callback(true, result);
                                    setTimeout(checkSaveStatus, 2)
                                }
                                if (result.eventType == ESL_CONSTANTS.EVENT_ALLSAVE_COMPLETE) {
                                    callback(true, result);
                                }
                            } else {
                                callback(false, null);
                            }
                        });
                    };
                    setTimeout(checkSaveStatus, 2)
                } else {
                    callback(false, null);
                }
            }
        }
        requestXML.open("POST", this.serverURL + "/Save", true);
        requestXML.setRequestHeader("Content-Type", "text/plain");
        const json = JSON.stringify(params);
        requestXML.send(json);
    }

    ScanAndSave_Simple(connectionParam, scanParam, saveParam, callBack) {
        const eslObj = new ESLClass();
        
        eslObj.Open(connectionParam, function(isSuccess, result) {
            if (isSuccess == true) {
                eslObj.Scan(scanParam, function(isSuccess, result) {
                    if (isSuccess) {
                        if (result.eventType == ESL_CONSTANTS.EVENT_SCANPAGE_COMPLETE) {
                            callBack(true, result);
                        }
                        
                        if (result.eventType == ESL_CONSTANTS.EVENT_ALLSCAN_COMPLETE) {
                            callBack(true, result);
                            
                            eslObj.Save(saveParam, function(isSuccess, result) {
                                if (isSuccess == true) {
                                    if (result.eventType == ESL_CONSTANTS.EVENT_SAVEPAGE_COMPLETE) {
                                        callBack(true, result);
                                    }
                                    if (result.eventType == ESL_CONSTANTS.EVENT_ALLSAVE_COMPLETE) {
                                        const saveResult = result;
                                        eslObj.Close(function(isSuccess, result) {
                                            if (isSuccess == true) {
                                                callBack(true, saveResult);
                                            } else {
                                                callBack(false, result);
                                            }
                                        });
                                    }
                                } else {
                                    callBack(false, result);
                                    eslObj.Close(function(isSuccess, result) {});
                                }
                            });
                        }
                    } else {
                        callBack(false, result);
                        eslObj.Close(function(isSuccess, result) {});
                    }
                });
            } else {
                callBack(false, result);
            }
        });
    }
}

// 创建工厂函数
const createScanner = () => {
    return new ESLClass();
};

// 将Promise包装的扫描功能作为单独函数导出
const scanDocument = (connectionParam, scanParam, saveParam) => {
    return new Promise((resolve, reject) => {
        const scanner = new ESLClass();
        scanner.ScanAndSave_Simple(
            connectionParam, 
            scanParam, 
            saveParam, 
            (success, result) => {
                if (success) {
                    resolve(result);
                } else {
                    reject(result || new Error('扫描失败'));
                }
            }
        );
    });
};

// 导出
export {
    ERROR_CODE,
    ESL_CONSTANTS,
    ESLClass,
    createScanner,
    scanDocument
};

// 为了向后兼容也可以提供默认导出
export default {
    ERROR_CODE,
    constants: ESL_CONSTANTS,
    ESLClass,
    createScanner,
    scanDocument
};